﻿using System.Data.SqlTypes;
using System.IO;
using System.Linq;
//using GeoAPI.Geometries;
using Microsoft.SqlServer.Types;
//using NetTopologySuite.IO;

namespace HashFoo.SqlServer.Spatial
{
    /// <summary>
    /// Utilities for MsSql DB types
    /// </summary>
    public static class SqlSpatialTypesUtil
    {
        ///// <summary>
        ///// Reads a GeoApi IGeometry from a MsSql Geometry.
        ///// </summary>
        ///// <param name="sqlGeometry">The MsSql Geometry to read</param>
        ///// <returns>The GeoApi geometry</returns>
        //public static IGeometry AsGeoApiGeometry(this SqlGeometry sqlGeometry)
        //{
        //    var reader = new WKBReader();
        //    var geom = reader.Read(sqlGeometry.STAsBinary().Value);
        //    geom.SRID = sqlGeometry.STSrid.Value;
        //    return geom;
        //}

        ///// <summary>
        ///// Gets a MsSql geometry from a GeoApi geometry.
        ///// </summary>
        ///// <param name="geometry">The geometry to transform</param>
        ///// <returns>The MsSql geometry</returns>
        //public static SqlGeometry AsSqlGeometry(this IGeometry geometry)
        //{
        //    geometry.SRID = geometry.SRID == 0 ? 4326 : geometry.SRID;
        //    return SqlGeometry.STGeomFromText(new SqlChars(geometry.AsText().ToArray()), geometry.SRID);
        //}

        /// <summary>
        /// Gets the MSSql geography type from a raw serialized byte[] (not WKB).
        /// </summary>
        /// <param name="data">The raw, serialized geography</param>
        /// <returns>A MSSql Geography instance</returns>
        public static SqlGeography GetSqlGeography(this byte[] data)
        {
            var memReader = new MemoryStream(data);
            using (memReader)
            {
                var g = new SqlGeography();
                using (var reader = new BinaryReader(memReader))
                {
                    g.Read(reader);
                    return g;
                }
            }
        }

        /// <summary>
        /// Gets the MSSql geometry type from a raw serialized byte[] (not WKB).
        /// </summary>
        /// <param name="data">The raw, serialized geometry</param>
        /// <returns>A MSSql Geometry instance</returns>
        public static SqlGeometry GetSqlGeometry(this byte[] data)
        {
            var memReader = new MemoryStream(data);
            using (memReader)
            {
                var g = new SqlGeometry();
                using (var reader = new BinaryReader(memReader))
                {
                    g.Read(reader);
                    return g;
                }
            }
        }

        /// <summary>
        /// Serializes an mssql geography to its DB form (not WKB)
        /// </summary>
        /// <param name="sqlGeography">The geography to serialize</param>
        /// <returns>The serizlized data</returns>
        public static byte[] Serialize(this SqlGeography sqlGeography)
        {
            using (var memStream = new MemoryStream())
            using (var writer = new BinaryWriter(memStream))
            {
                sqlGeography.Write(writer);
                return memStream.ToArray();
            }
        }

        /// <summary>
        /// Serializes an mssql geometry to its DB form (not WKB)
        /// </summary>
        /// <param name="sqlGeometry">The geometry to serialize</param>
        /// <returns>The serizlized data</returns>
        public static byte[] Serialize(this SqlGeometry sqlGeometry)
        {
            using (var memStream = new MemoryStream())
            using (var writer = new BinaryWriter(memStream))
            {
                sqlGeometry.Write(writer);
                return memStream.ToArray();
            }
        }
    }
}